#include "QCustomWidget.h"

#include <Windows.h>
#include <dwmapi.h>
#include <QWindowStateChangeEvent>

#pragma comment(lib,"dwmapi.lib")

void QCustomWidget::showMaximized(bool maximised)
{
	if (maximised)
	{
		QWidget::showMaximized();
	}
	else
	{
		QWidget::showNormal();
	}
}

QCustomWidget::QCustomWidget(QWidget* parent) :
	QWidget(parent),
	m_borderThinness(5),
	m_canRank(true),
	m_roundStyle(true)
{
	setWindowFlag(Qt::FramelessWindowHint);

	setRoundStyle(m_roundStyle);

	SetWindowLong(reinterpret_cast<HWND>(winId()), GWL_STYLE,
		GetWindowLong(reinterpret_cast<HWND>(winId()), GWL_STYLE) | WS_CAPTION);
	SetWindowLong(reinterpret_cast<HWND>(winId()), GWL_STYLE,
		GetWindowLong(reinterpret_cast<HWND>(winId()), GWL_STYLE) | WS_SIZEBOX);
	SetWindowLong(reinterpret_cast<HWND>(winId()), GWL_STYLE,
		GetWindowLong(reinterpret_cast<HWND>(winId()), GWL_STYLE) & ~WS_SYSMENU);
}

QList<QWidget*> QCustomWidget::titleBars()
{
	return m_titleBars;
}

void QCustomWidget::addTitleBar(QWidget* titleBar)
{
	if (titleBar)
	{
		m_titleBars.append(titleBar);
	}
}

void QCustomWidget::removeTitleBar(QWidget* titleBar)
{
	if (titleBar)
	{
		m_titleBars.removeOne(titleBar);
	}
}

void QCustomWidget::setRoundStyle(bool roundStyle)
{
	m_roundStyle = roundStyle;

	if (roundStyle)
	{
		MARGINS margins{ -1 };
		DwmExtendFrameIntoClientArea((HWND)winId(), &margins);
	}
	else
	{
		MARGINS margins{ 0 };
		DwmExtendFrameIntoClientArea((HWND)winId(), &margins);
	}
}

void QCustomWidget::setBorderThinness(qint32 borderThinness)
{
	m_borderThinness = borderThinness;
}

bool QCustomWidget::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
	if (eventType == "windows_generic_MSG")
	{
		MSG* msg = static_cast<MSG*>(message);

		switch (msg->message)
		{

		case WM_NCHITTEST:
			qDebug() << QCursor::pos() << pos();

			for (auto& titleBar : m_titleBars)
			{
				if (titleBar->geometry().contains(QCursor::pos() - pos()))
				{
					*result = HTCAPTION;
					break;
				}
			}

			if (QRect(geometry().left(), geometry().top() + m_borderThinness,
				m_borderThinness, geometry().height() - 2 * m_borderThinness)
				.contains(QCursor::pos()))
			{
				*result = HTLEFT;
			}
			else if (QRect(geometry().left() + m_borderThinness, geometry().top(),
				geometry().width() - 2 * m_borderThinness, m_borderThinness)
				.contains(QCursor::pos()))
			{
				*result = HTTOP;
			}
			else if (QRect(geometry().right() - m_borderThinness, geometry().top() + m_borderThinness,
				m_borderThinness, geometry().height() - 2 * m_borderThinness)
				.contains(QCursor::pos()))
			{
				*result = HTRIGHT;
			}
			else if (QRect(geometry().left() + m_borderThinness, geometry().bottom() - m_borderThinness,
				geometry().width() - 2 * m_borderThinness, m_borderThinness)
				.contains(QCursor::pos()))
			{
				*result = HTBOTTOM;
			}
			else if (QRect(geometry().left(), geometry().top(),
				m_borderThinness, m_borderThinness)
				.contains(QCursor::pos()))
			{
				*result = HTTOPLEFT;
			}
			else if (QRect(geometry().left(), geometry().bottom() - m_borderThinness,
				m_borderThinness, m_borderThinness)
				.contains(QCursor::pos()))
			{
				*result = HTBOTTOMLEFT;
			}
			else if (QRect(geometry().right() - m_borderThinness, geometry().top(),
				m_borderThinness, m_borderThinness)
				.contains(QCursor::pos()))
			{
				*result = HTTOPRIGHT;
			}
			else if (QRect(geometry().right() - m_borderThinness, geometry().bottom() - m_borderThinness,
				m_borderThinness, m_borderThinness)
				.contains(QCursor::pos()))
			{
				*result = HTBOTTOMRIGHT;
			}

			return *result;

		case WM_NCCALCSIZE:
			if (msg->wParam)
				*result = 0;
			return true;

		default:
			return QWidget::nativeEvent(eventType, message, result);
		}
	}

	return QWidget::nativeEvent(eventType, message, result);
}

void QCustomWidget::changeEvent(QEvent* event)
{
	if (event->type() == QEvent::WindowStateChange)
	{
		emit windowStateChanged(windowState());
	}

	return QWidget::changeEvent(event);
}
